vignettes/gallery_transforms.Rmd
gallery_transforms.RmdThis document is an attempt to reproduce some of the charts shown in Observable Plot documentation.
data(anscombe_obs)
obsplot(anscombe_obs, height = 240) |>
mark_frame() |>
mark_dot(x = "x", y = "y") |>
facet(x = "series") |>
opts(grid = TRUE, inset = 10)
data(barley)
# precompute domains
y_domain <- reorder(barley$variety, barley$yield, median) |> levels() |> rev()
fy_domain <- reorder(barley$site, barley$yield, median) |> levels() |> rev()
obsplot(barley, height = 800) |>
mark_frame() |>
mark_dot(x = "yield", y = "variety", stroke = "year") |>
facet(y = "site", marginRight = 90) |>
scale_x(nice = TRUE) |>
scale_y(domain = y_domain, inset = 5) |>
scale_fy(domain = fy_domain) |>
scale_color(type = "categorical") |>
opts(marginLeft = 110, grid = TRUE)
library(palmerpenguins)
data(penguins)
obsplot(penguins, height = 600) |>
mark_frame() |>
mark_dot(penguins, x = "bill_depth_mm", y = "bill_length_mm", r = 2, fill = "#ddd") |>
mark_dot(x = "bill_depth_mm", y = "bill_length_mm") |>
facet(x = "sex", y = "species", marginRight = 80) |>
opts(grid = TRUE)
data(penguins)
obsplot(penguins) |>
mark_barY(transform_groupX(y = "count", x = "species")) |>
mark_ruleY(0) |>
scale_y(grid = TRUE)
obsplot(penguins) |>
mark_barY(transform_groupX(y = "count", x = "species")) |>
mark_ruleY(0) |>
scale_x(domain = names(sort(table(penguins$species))), reverse = TRUE) |>
scale_y(grid = TRUE)
obsplot(penguins) |>
mark_barY(transform_groupX(y = "proportion", x = "species")) |>
mark_ruleY(0) |>
scale_y(grid = TRUE, percent = TRUE)
penguins$body_mass_kg <- penguins$body_mass_g / 1000
obsplot(penguins) |>
mark_barY(transform_groupX(list(y = "sum"), x = "species", y = "body_mass_kg")) |>
mark_ruleY(0) |>
scale_y(grid = TRUE, label = "↑ Total mass (kg)")
obsplot(penguins, height = 150) |>
mark_dot(y = "species", x = "body_mass_g") |>
mark_ruleY(
transform_groupY(list(x1 = "min", x2 = "max"), y = "species", x = "body_mass_g")
) |>
mark_tickX(transform_groupY(list(x = "median"), y = "species", x = "body_mass_g", stroke = "red")) |>
scale_x(inset = 6) |>
scale_y(label = NULL) |>
opts(marginLeft = 60)
data(mobydick1)
obsplot(mobydick1) |>
mark_barY(
transform_groupX(y = "count")
) |>
mark_ruleY(0) |>
scale_y(grid = TRUE)
obsplot(mobydick1) |>
mark_barY(
transform_groupX(y = "proportion", filter = JS('d => /[AEIOUY]/.test(d)'))
) |>
mark_ruleY(0) |>
scale_y(grid = TRUE, percent = TRUE)
data(penguins)
obsplot(penguins) |>
mark_barY(transform_groupX(y = "count", x = "sex")) |>
mark_ruleY(0) |>
facet(x = "species") |>
scale_x(tickFormat = JS('d => d === null ? "N/A" : d')) |>
scale_y(grid = TRUE)
obsplot(penguins) |>
mark_barY(transform_groupX(y = "proportion-facet", x = "sex")) |>
mark_ruleY(0) |>
facet(x = "species") |>
scale_x(tickFormat = JS('d => d === null ? "N/A" : d')) |>
scale_y(grid = TRUE, percent = TRUE)
obsplot(penguins) |>
mark_barY(transform_groupX(y = "count", x = "species", fill = "sex")) |>
mark_ruleY(0) |>
scale_y(grid = TRUE)
obsplot(penguins, height = 60) |>
mark_barX(
transform_stackX(
transform_groupZ(x = "proportion", fill = "sex")
)
) |>
mark_text(
transform_stackX(
transform_groupZ(
list(x = "proportion", text = "first"),
z = "sex", text = "sex")
)
) |>
mark_ruleX(c(0, 1)) |>
scale_x(percent = TRUE)
obsplot(penguins) |>
mark_barY(transform_groupZ(y = "proportion-facet", fill = "sex")) |>
mark_ruleY(c(0, 1)) |>
facet(x = "species") |>
scale_y(grid = TRUE, percent = TRUE)
data(seattle)
obsplot(seattle, height = 300) |>
mark_cell(
transform_group(
fill = "max",
x = JS('d => d.date.getUTCDate()'),
y = JS('d => d.date.getUTCMonth()'),
fill = "temp_max",
inset = 0.5
)
) |>
scale_color(scheme = "BuRd") |>
scale_y(tickFormat = JS('Plot.formatMonth()')) |>
opts(padding = 0)
data(athletes)
obsplot(athletes) |>
mark_rectY(transform_binX(y = "count", x = "weight")) |>
mark_ruleY(0) |>
scale_y(grid = TRUE)
obsplot(athletes) |>
mark_rectY(transform_binX(y = "count", x = "weight", inset = 0)) |>
mark_ruleY(0) |>
scale_x(round = TRUE) |>
scale_y(grid = TRUE)
obsplot(athletes) |>
mark_areaY(transform_binX(y = "count", x = "weight", fill = "#ccc")) |>
mark_lineY(transform_binX(y = "count", x = "weight")) |>
mark_ruleY(0) |>
scale_y(grid = TRUE)
obsplot(athletes) |>
mark_rectY(transform_binX(y = "count", x = "weight", thresholds = "sturges")) |>
mark_ruleY(0) |>
scale_y(grid = TRUE)
obsplot(athletes) |>
mark_rectY(transform_binX(y = "count", x = "weight", cumulative = TRUE)) |>
mark_ruleY(0) |>
scale_y(grid = TRUE)
obsplot(athletes) |>
mark_rectY(transform_binX(y2 = "count", x = "weight", fill = "sex", mixBlendMode = "multiply")) |>
mark_ruleY(0) |>
scale_y(grid = TRUE)
obsplot(athletes) |>
mark_rectY(transform_binX(y = "count", x = "weight", fill = "sex")) |>
mark_ruleY(0) |>
scale_y(grid = TRUE)
obsplot(athletes, height = 60) |>
mark_barX(transform_binX(fill = "count", x = "weight")) |>
scale_x(round = TRUE) |>
scale_color(scheme = "YlGnBu")
obsplot(athletes) |>
mark_rect(transform_bin(fill = "count", x = "weight", y = "height", inset = 0)) |>
scale_color(scheme = "YlGnBu") |>
opts(round = TRUE, grid = TRUE)
obsplot(athletes) |>
mark_rect(transform_bin(fillOpacity = "count", x = "weight", y = "height", fill = "sex", inset = 0)) |>
opts(round = TRUE, grid = TRUE)
obsplot(athletes) |>
mark_dot(transform_bin(r = "count", x = "weight", y = "height")) |>
scale_r(range = c(0, 10)) |>
opts(round = TRUE, grid = TRUE)
obsplot(athletes) |>
mark_dot(transform_bin(r = "count", x = "weight", y = "height", stroke = "sex")) |>
scale_r(range = c(0, 10)) |>
opts(round = TRUE, grid = TRUE)
obsplot(athletes, height = 60) |>
mark_dot(transform_binX(r = "count", x = "weight")) |>
scale_r(range = c(0, 14))
sports_by_weight <- levels(reorder(athletes$sport, athletes$weight, median, na.rm = TRUE))
obsplot(athletes, height = 600) |>
mark_barX(transform_binX(fill = "proportion-facet", x = "weight", inset = 0.5)) |>
facet(marginLeft = 100, y = "sport") |>
scale_color(scheme = "YlGnBu") |>
scale_x(round = TRUE, grid = TRUE) |>
scale_fy(domain = sports_by_weight, label = NULL) |>
opts(marginLeft = 100, padding = 0)
data(crimea)
obsplot(crimea) |>
mark_lineY(x = "date", y = "deaths", stroke = "cause") |>
mark_ruleY(0) |>
scale_y(grid = TRUE)
obsplot(crimea) |>
mark_areaY(x = "date", y2 = "deaths", fill = "cause", mixBlendMode = "multiply") |>
mark_ruleY(0) |>
scale_y(grid = TRUE)
obsplot(crimea) |>
mark_areaY(x = "date", y = "deaths", fill = "cause") |>
mark_ruleY(0) |>
scale_y(grid = TRUE)
obsplot(crimea) |>
mark_barY(x = "date", y = "deaths", fill = "cause") |>
mark_ruleY(0) |>
scale_x(label = NULL, tickFormat = JS('d => d.toLocaleString("en", {month: "narrow"})'))
data(unemployment)
obsplot(unemployment) |>
mark_areaY(transform_stackY(x = "date", y = "unemployed", fill = "industry", title = "industry")) |>
mark_ruleY(0) |>
scale_y(grid = TRUE, label = '↑ Unemployed (thousands)')
obsplot(unemployment) |>
mark_areaY(transform_stackY(offset = "silhouette", x = "date", y = "unemployed", fill = "industry")) |>
scale_y(grid = TRUE, label = '↑ Unemployed (thousands)')
obsplot(unemployment) |>
mark_areaY(transform_stackY(offset = "wiggle", x = "date", y = "unemployed", fill = "industry")) |>
scale_y(grid = TRUE, label = '↑ Unemployed (thousands)')
obsplot(unemployment) |>
mark_areaY(transform_stackY(curve = "catmull-rom", x = "date", y = "unemployed", fill = "industry", order = "value")) |>
mark_ruleY(0) |>
scale_y(grid = TRUE, label = '↑ Unemployed (thousands)')
data(riaa)
xy <- list(x = "year", y = "revenue", z = "format", order = "appearance", reverse = TRUE)
obsplot(riaa) |>
mark_areaY(
transform_stackY(
append(
xy,
list(fill = "group", title = JS('d => `${d.format}\n${d.group}`'))
)
)
) |>
mark_lineY(
transform_stackY1(
append(
xy,
list(stroke = "white", strokeWidth = 1)
)
)
) |>
mark_ruleY(0) |>
scale_y(grid = TRUE, label = "↑ Annual revenue (billions, adj.)", transform = JS('d => d / 1000'))
xy <- list(x = "year", y = "revenue", z = "format", order = "appearance", reverse = TRUE, offset = "expand")
obsplot(riaa) |>
mark_areaY(
transform_stackY(
append(
xy,
list(fill = "group", title = JS('d => `${d.format}\n${d.group}`'))
)
)
) |>
mark_lineY(
transform_stackY1(
append(
xy,
list(stroke = "white", strokeWidth = 1)
)
)
) |>
mark_ruleY(c(0, 1)) |>
scale_y(grid = TRUE, label = "↑ Annual revenue (billions, adj.)", transform = JS('d => d / 1000'))
data(congress)
obsplot(congress, height = 300) |>
mark_dot(
transform_stackY2(
x = JS('d => 2021 - d.birth'),
y = JS('d => d.gender === "M" ? 1 : d.gender === "F" ? -1 : 0'),
fill = "gender"
)
) |>
mark_ruleY(0) |>
scale_x(label = "Age →", nice = TRUE) |>
scale_y(
grid = TRUE, label = "← Women · Men →",
labelAnchor = "center",
tickFormat = JS('Math.abs')
)
obsplot(congress, height = 280) |>
mark_barX(
transform_stackX(
transform_groupZ(x = "proportion-facet", fill = "gender")
)
) |>
mark_text(
transform_stackX(
transform_groupZ(
list(x = "proportion-facet", text = "first"),
z = "gender", text = JS('d => d.gender === "F" ? "Women" : d.gender === "M" ? "Men" : null')
)
)
) |>
mark_ruleX(c(0, 1)) |>
facet(y = JS('d => Math.floor((2021 - d.birth) / 10) * 10')) |>
scale_x(percent = TRUE)
data(iowa)
obsplot(iowa) |>
mark_areaY(
transform_stackY(x = "year", y = "net_generation", fill = "source", title = "source")
) |>
mark_ruleY(0) |>
scale_y(grid = TRUE, label = "↑ Net generation (million MWh)", transform = JS('d => d / 1000'))
values <- rnorm(500)
obsplot(values, height = 200) |>
mark_lineY(transform_map(list(y = "cumsum"), y = values))
obsplot(values, height = 200) |>
mark_lineY(transform_mapY("cumsum", y = values))
data(sftemp)
obsplot(sftemp) |>
mark_areaY(x = "date", y1 = "low", y2 = "high", curve = "step", fill = "#ccc") |>
mark_line(
transform_windowY(x = "date", y = "low", k = 7, curve = "step", stroke = "blue")
) |>
mark_line(
transform_windowY(x = "date", y = "high", k = 7, curve = "step", stroke = "red")
) |>
scale_y(grid = TRUE, label = "↑ Daily temperature range (°F)")
data(stocks)
obsplot(stocks) |>
mark_ruleY(1) |>
mark_line(transform_normalizeY(x = "Date", y = "Close", stroke = "Symbol")) |>
mark_text(
transform_selectLast(
transform_normalizeY(
x = "Date", y = "Close", stroke = "Symbol",
text = "Symbol", textAnchor = "start", dx = 3
)
)
) |>
scale_y(
type = "log", grid = TRUE, label = "↑ Change in price (%)",
tickFormat = JS("x => d3.format('+d')((x - 1) * 100)")
) |>
opts(marginRight = 40)##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
data(stateage)
# Pivot to longer format
stateage <- stateage |>
tidyr::pivot_longer(!name, names_to = "age", values_to = "population")
# Get states order by proportion of >=80
state_order <- stateage |>
group_by(name) |>
mutate(
total_pop = sum(population),
prop = population / total_pop
) |>
filter(age == "≥80") |>
arrange(desc(prop))
xy <- transform_normalizeX(basis = "sum", z = "name", x = "population", y = "name")
obsplot(stateage, height = 660) |>
mark_ruleX(x = 0) |>
mark_ruleY(transform_groupY(list(x1 = "min", x2 = "max"), xy)) |>
mark_dot(xy, fill = "age", title = "age") |>
mark_text(transform_selectMinX(xy), textAnchor = "end", dx = -6, text = "name") |>
scale_x(axis = "top", label = "Percent (%) →", transform = JS("d => d * 100")) |>
scale_y(
domain = state_order$name,
axis = NULL
) |>
scale_color(scheme = "spectral", domain = unique(stateage$age)) |>
opts(grid = TRUE)